package com.zscat.mallplus.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jpay.weixin.api.WxPayApi;
import com.zscat.mallplus.dms.entity.DmsOrder;
import com.zscat.mallplus.dms.service.*;
import com.zscat.mallplus.enums.OrderStatus;
import com.zscat.mallplus.enums.RoomStatus;
import com.zscat.mallplus.enums.TaskType;
import com.zscat.mallplus.qsg.*;
import com.zscat.mallplus.qsg.impl.MqttConfigService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
public class Myquartz extends QuartzJobBean {

    @Autowired
    private IDmsOrderService orderService;
    @Autowired
    private WxMsgService wxMsgService;
    @Autowired
    private IRoomService roomService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IQsgStoreService storeService;
    @Autowired
    private IDeviceTaskService taskService;
    @Autowired
    private MqttConfigService mqttConfigService;
    @Autowired
    private IGatewayDeviceService gatewayDeviceService;
    @Autowired
    private IQsgGatewayInfoService gatewayInfoService;
    @Autowired
    private IntegralService integralService;

    @Autowired
    private IDmsOrderSharingDetailService sharingDetailService;

    @Override
    protected void executeInternal(JobExecutionContext context){
        //获取当前下所有当前时间结束的订单
        String date = DateUtil.dateToStr(new Date(), "yyyy/MM/dd HH:mm");
        QueryWrapper qw = new QueryWrapper();
        qw.eq("end_time", date);
        List<Integer> statuses = new ArrayList<>();
        statuses.add(OrderStatus.HAS_PAYMONEY.getValue());
        statuses.add(OrderStatus.PAYMENT.getValue());
        qw.in("order_status", statuses);
        List<DmsOrder> orders = orderService.list(qw);
        if (null != orders && orders.size() > 0) {
            for (DmsOrder order : orders) {
                if (order.getIsSharing() == 1) {//0无需分账 1需要分账 2分账完成
                    try {
                        QsgDevice device = deviceService.getById(order.getDeviceId());
                        QsgStore store = storeService.getById(device.getStoreId());
                        //设备是离线状态
                        Date expireTime = store.getSimOutTime();
                        Date currentDate = new Date();
                        if(1 == device.getOlStatus() || expireTime.before(currentDate) || 446 == store.getId()){
                            continue;
                        }
                        //待分账
                        Map<String, String> params = new TreeMap<>();
                        params.put("mch_id", store.getServerMchId());//服务商
                        params.put("appid", store.getServerAppid());//服务商appid
                        params.put("sub_mch_id", store.getMchId());//出资方 根据订单的storeId获取
                        params.put("transaction_id", order.getWxOrderSn());//微信订单号 根据订单获取
                        params.put("nonce_str", System.currentTimeMillis() + "");
                        params.put("out_order_no", order.getOrderSn());
                        JSONObject jsonObject = new JSONObject();//分账的收款方信息
                        jsonObject.put("type", "MERCHANT_ID");
                        jsonObject.put("account", store.getReceiverMchid());
                        BigDecimal amount = order.getPrice().multiply(new BigDecimal(100).multiply(new BigDecimal(store.getScale()))).setScale(0, BigDecimal.ROUND_DOWN);
                        jsonObject.put("amount", amount);
                        jsonObject.put("description", store.getName() + "_" + order.getOrderSn());//店铺名+订单号
                        JSONArray jsonArray = new JSONArray();
                        jsonArray.add(jsonObject);
                        params.put("receivers", jsonArray.toJSONString());
                        String sign = WechatUtil.arrayHmacsha(params, store.getServerKey());
                        params.put("sign", sign);
                        //上线后需改为线上模式
                        String i = WxPayApi.profitsharing(params, store.getServerCertPath(), store.getServerMchId());//参数 证书地址 服务商证书密码默认即商户号
                        Map<String, Object> resultUn = XmlUtil.xmlStrToMap(i);
                        String return_code = MapUtils.getString("return_code", resultUn);
                        String result_code = MapUtils.getString("result_code", resultUn);
                        if (result_code.equalsIgnoreCase("SUCCESS") && return_code.equalsIgnoreCase("SUCCESS")) {
                            order.setIsSharing(2);
                            orderService.updateById(order);
                            //添加分账明细到分账记录表
                            QsgOrderSharingDetail sharingDetail = new QsgOrderSharingDetail();
                            sharingDetail.setTransactionId(order.getWxOrderSn());
                            sharingDetail.setOutOrderNo(order.getOrderSn());
                            sharingDetail.setServerMchid(store.getServerMchId());
                            sharingDetail.setServerAppid(store.getServerAppid());
                            sharingDetail.setSubMchid(store.getMchId());
                            sharingDetail.setStoreId(store.getId());
                            sharingDetail.setReceiverMchid(store.getReceiverMchid());
                            sharingDetail.setAmount(amount);
                            sharingDetail.setCreateDatetime(new Date());
                            sharingDetailService.save(sharingDetail);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                QueryWrapper yyQw = new QueryWrapper();
                yyQw.eq("start_time", order.getEndTime());
                yyQw.eq("device_id", order.getDeviceId());
                yyQw.eq("member_id", order.getMemberId());
                yyQw.eq("order_status", OrderStatus.HAS_PAYMONEY.getValue());
                DmsOrder currentOrder = orderService.getOne(yyQw);//当前进行的订单的续费订单
                if (null == currentOrder) {
                    //修改状态并发送通知
                    order.setOrderStatus(OrderStatus.COMPLETED.getValue());
                    QsgDevice device = deviceService.getById(order.getDeviceId());
                    //如果是台球后付费的积分支付订单
                    if(device.getIsBilliard() == 0 && device.getIsDepositDevice() == 0 && 1 == order.getPayMethod().intValue()){
                        BigDecimal payMoney = orderService.calPayMoney(order);
                        QueryWrapper qwone = new QueryWrapper();
                        qwone.eq("member_id",order.getMemberId());
                        qwone.eq("store_id",order.getStoreId());
                        QsgIntegral integral = integralService.getOne(qwone);
                        int payIntegral = payMoney.multiply(new BigDecimal(100)).intValue();
                        int refundIntegral = integral.getIntegral() - payIntegral;
                        if(refundIntegral < 0){
                            refundIntegral = 0;
                        }
                        integral.setIntegral(refundIntegral);
                        integralService.updateById(integral);

                        Date currentTime = new Date();
                        order.setActEndTime(currentTime);
                        order.setEndTime(DateUtil.dateToString(currentTime,"yyyy/MM/dd HH:mm"));
                        order.setPrice(payMoney);
                        order.setIntegral(payIntegral);
                    }
                    orderService.updateById(order);
                    QueryWrapper queryWrapper = new QueryWrapper();
                    queryWrapper.eq("device_id", device.getId());
                    QsgRoom room = roomService.getOne(queryWrapper);
                    //如果是台球后付费产品直接更新房间状态为可预订
                    if(device.getIsBilliard() == 0 && device.getIsDepositDevice() == 0){
                        room.setStatus(RoomStatus.ONLINE.getValue());
                        room.setBeforeStatus(room.getStatus());
                    }else{
                        room.setStatus(RoomStatus.WAITCLEAN.getValue());
                        room.setBeforeStatus(room.getStatus());
                    }
                    roomService.updateById(room);
                    //同步关闭设备关联的空调
                    roomService.closeAirControl(device);
                    wxMsgService.sendDasaoMsg(order);
                } else {
                    //后续有续费,所以不改房间状态 但是会修改订单状态
                    order.setOrderStatus(OrderStatus.COMPLETED.getValue());
                    orderService.updateById(order);
//                    wxMsgService.sendDasaoMsg(order);
                }
            }
        }

        //
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("status", 1);
        queryWrapper.eq("task_type", TaskType.GUANGZHOU_DEVICE_OPEN_DOOR.getValue());
        List<QsgDeviceTask> tasks = taskService.list(queryWrapper);
        if (tasks.size() > 0) {
            for (QsgDeviceTask task : tasks) {
                Long createTime = task.getCreateDatetime().getTime();
                long dif = System.currentTimeMillis() - createTime;
                if (dif >= 60000) {
                    task.setStatus(3);
                    taskService.updateById(task);
                    QsgDevice device = deviceService.getById(task.getDeviceId());
                    QsgStore store = storeService.getById(device.getStoreId());
                    if (store.getLockMode()==1){
                        continue;
                    }
                    //设备是离线状态
                    Date expireTime = store.getSimOutTime();
                    Date currentDate = new Date();
                    if(1 == device.getOlStatus() || expireTime.before(currentDate) || 446 == store.getId()){
                        continue;
                    }
                    try {
                        JSONObject data = new JSONObject();
                        JSONObject header = new JSONObject();
                        JSONObject body = new JSONObject();
                        header.put("Code", "1004");
                        header.put("Time", System.currentTimeMillis());
                        header.put("Sign", "lvzaina");
                        data.put("Header", header);
                        body.put("Delay", 0);
                        body.put("Cmd", "RemoteOpenDoor");
                        body.put("MsgId", 1682220193);
                        body.put("Lock", 189);
                        body.put("Type", 0);
                        body.put("ID", 0);
                        data.put("Body", body);
                        mqttConfigService.publish("topic/receive/" + task.getDeviceCode(), data.toJSONString());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        //监听任务表任务10、11、12 的有效任务,每分钟执行小于当前时间的这些任务
        //五分钟、三十分钟任务发送喇叭消息，结束时发送喇叭消息和关电任务,关电任务需要此房间的所有设备都断电
        String currentTime = DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
        QueryWrapper queryWrapper1 = new QueryWrapper();
        List<Integer> types = new ArrayList<>();
        types.add(TaskType.GATEWAY_DELAY_CLOSEDOOR_REPORT.getValue());
        types.add(TaskType.GATEWAY_TEN_REPORT.getValue());
        types.add(TaskType.GATEWAY_HALF_HOUR_REPORT.getValue());
        types.add(TaskType.GATEWAY_FIVE_MINUTE_REPORT.getValue());
        types.add(TaskType.GATEWAY_END_REPORT.getValue());
        queryWrapper1.in("task_type", types);
        queryWrapper1.le("end_time", currentTime);
        queryWrapper1.eq("status",0);
        //taskList:小于当前时间的网关任务
        List<QsgDeviceTask> taskList = taskService.list(queryWrapper1);
        if (taskList.size() > 0) {
            try {
                for (QsgDeviceTask task : taskList) {
                    if (task.getTaskType() == TaskType.GATEWAY_DELAY_CLOSEDOOR_REPORT.getValue()){
                        QueryWrapper doorQw = new QueryWrapper();
                        doorQw.eq("is_door", 1);
                        doorQw.eq("device_id", task.getDeviceId());
                        List<QsgGatewayDevice> doorDevices = gatewayDeviceService.list(doorQw);
                        if(null != doorDevices && !doorDevices.isEmpty()){
                            for (QsgGatewayDevice device : doorDevices){
                                QsgGatewayInfo gatewayInfo = gatewayInfoService.getById(device.getGatewayId());
                                JSONObject data = new JSONObject();
                                data.put("CommandId",UUID.randomUUID());
                                data.put("SystemCode","csqsg");
                                data.put("GatewayIeee",gatewayInfo.getSerialno());
                                data.put("SensorIeee",device.getIeeeEpAddr());
                                data.put("Command","Off");
                                mqttConfigService.publish("/toGW/"+gatewayInfo.getMacAddr(),data.toJSONString());
                            }
                        }
                    }
                    QueryWrapper gatewayQw = new QueryWrapper();
                    gatewayQw.eq("is_voice", 1);
                    gatewayQw.eq("device_id", task.getDeviceId());
                    List<QsgGatewayDevice> voices = gatewayDeviceService.list(gatewayQw);
                    if (task.getTaskType() == TaskType.GATEWAY_END_REPORT.getValue()) {
                        if (voices.size()>0){
                            this.report(voices,154);
                        }
                        QueryWrapper queryWrapper2 = new QueryWrapper();
                        queryWrapper2.eq("is_voice", 0);
                        queryWrapper2.eq("device_id", task.getDeviceId());
                        //devices:当前房间不是喇叭的网关设备
                        List<QsgGatewayDevice> devices = gatewayDeviceService.list(queryWrapper2);
                        if (devices.size()>0){
                            for (QsgGatewayDevice device : devices){
                                Integer isAirControl = device.getIsAirControl();
                                //如果是空调伴侣,并且没有使用的订单就关闭
                                if(1 == isAirControl.intValue()){
                                     int usingNum = getUsingOrder(device);
                                    if(usingNum == 0){
                                        closeAirControl(device);
                                    }
                                }else{
                                    QsgGatewayInfo gatewayInfo = gatewayInfoService.getById(device.getGatewayId());
                                    JSONObject data = new JSONObject();
                                    data.put("CommandId",UUID.randomUUID());
                                    data.put("SystemCode","csqsg");
                                    data.put("GatewayIeee",gatewayInfo.getSerialno());
                                    data.put("SensorIeee",device.getIeeeEpAddr());
                                    data.put("Command","Off");
                                    mqttConfigService.publish("/toGW/"+gatewayInfo.getMacAddr(),data.toJSONString());
                                }
                            }
                        }
                    }
                    if (task.getTaskType() == TaskType.GATEWAY_HALF_HOUR_REPORT.getValue()){
                        if (voices.size()>0){
                            this.report(voices,153);
                        }
                    }
                    if (task.getTaskType() == TaskType.GATEWAY_TEN_REPORT.getValue()){
                        if (voices.size()>0){
                            this.report(voices,155);
                        }
                    }
                    if (task.getTaskType() == TaskType.GATEWAY_FIVE_MINUTE_REPORT.getValue()){
                        if (voices.size()>0){
                            this.report(voices,160);
                        }
                    }
                    task.setStatus(1);
                    taskService.updateById(task);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    private int getUsingOrder(QsgGatewayDevice device){
        String deviceIeeeEp = device.getIeeeEpAddr();
        QueryWrapper qwone = new QueryWrapper();
        qwone.eq("ieee_ep_addr",deviceIeeeEp);
        List<QsgGatewayDevice> devices = gatewayDeviceService.list(qwone);
        List<Long> deviceIds = new ArrayList<>();
        for (QsgGatewayDevice d: devices
        ) {
            deviceIds.add(d.getDeviceId());
        }
        QueryWrapper qworder = new QueryWrapper();
        qworder.in("device_id",deviceIds);
        qworder.eq("order_status", OrderStatus.HAS_PAYMONEY.getValue());
        qworder.le("start_time", DateUtil.dateToString(new Date(), "yyyy/MM/dd HH:mm:ss"));
        qworder.ge("end_time", DateUtil.dateToString(new Date(), "yyyy/MM/dd HH:mm:ss"));
        int usingNum = orderService.count(qworder);
        return usingNum;
    }

    /**
     * {
     * "CommandId": "658b2b7b-34a2-4a54-ad50-868d63ef4f42",
     * "SystemCode": "geewoo",
     * "GatewayIeee":"086BD7FFFE8AC51D",
     * "SensorIeee":"086BD7FFFE8ACAF401",
     * "Command":"PlayVoice",
     * "Index":1
     * }
     * @param voices
     */
    private void report(List<QsgGatewayDevice> voices,int index) throws Exception{
        QsgGatewayDevice voice = voices.get(0);
        QsgGatewayInfo gatewayInfo = gatewayInfoService.getById(voice.getGatewayId());
        JSONObject data = new JSONObject();
        data.put("CommandId","32c3e029-1411-4b91-b530-8436c91fe38d");
        data.put("SystemCode","csqsg");
        data.put("GatewayIeee",gatewayInfo.getSerialno());
        data.put("SensorIeee",voice.getIeeeEpAddr());
        data.put("Command","PlayVoice");
        data.put("Index",index);
        mqttConfigService.publish("/toGW/"+gatewayInfo.getMacAddr(),data.toJSONString());
    }


    private void closeAirControl(QsgGatewayDevice voice) throws Exception{
        QsgGatewayInfo gatewayInfo = gatewayInfoService.getById(voice.getGatewayId());
        JSONObject data = new JSONObject();
        data.put("CommandId",UUID.randomUUID());
        data.put("SystemCode","csqsg");
        data.put("GatewayIeee",gatewayInfo.getSerialno());
        data.put("SensorIeee",voice.getIeeeEpAddr());
        data.put("Command","IrLibControl");
        data.put("Button","ACClose");
        mqttConfigService.publish("/toGW/"+gatewayInfo.getMacAddr(),data.toJSONString());
    }
}
